package com.gitee.huanminabc.jtimerwheel.base;

import com.gitee.huanminabc.jtimerwheel.enums.TimerStatus;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.function.Consumer;

/**
 * 简要描述
 *
 * @Author: huanmin
 * @Date: 2022/11/30 17:16
 * @Version: 1.0
 * @Description: 文件作用详细描述....
 */
@Data
@Slf4j
public class TimerNodeData {
    public Map<String, TimerNode> currentNode ; //当前插槽下拥有的任务

    public TimerNodeData(Map<String, TimerNode> currentNode) {
        this.currentNode = currentNode;
    }

    //添加任务
    public  void addTask(TimerNode timerNode) {
        //取出旧的插槽,如果存在那么就删除
        if ( timerNode.timerNodeData!=null){
            timerNode.timerNodeData.delTask(timerNode.key);
        }

        //判断新的插槽下是否已经有任务
        if (currentNode.containsKey(timerNode.key)) {
            throw new TimerWheelException(timerNode.key+"任务已经存在添加失败-定时器出现了问题");
        }
        //添加到新插槽中
        timerNode.timerNodeData = this;
        currentNode.put(timerNode.key, timerNode);
    }

    //删除任务
    public  void delTask(String key) {
        TimerNode remove = currentNode.remove(key);
        if (remove == null) {
          throw new TimerWheelException(key+"任务不存在删除失败-定时器出现了问题");
        }
    }

    //在同一时间只运行一个插槽被遍历,不允许插槽被多个线程同时遍历
    public  void forEachTask(Consumer<TimerNode> function) {
        //用迭代器的方式,防止并发修改异常
        // 使用迭代器遍历并删除某个键
        Iterator<Map.Entry<String, TimerNode>> iterator = currentNode.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, TimerNode> entry = iterator.next();
            TimerNode timerNode = entry.getValue();
            //这个是如果外部将任务状态改为3那么在时间轮中也要删除
            if (timerNode.timerStatus == TimerStatus.NOTARIZE_DEL) {
                iterator.remove();
            } else {
                function.accept(timerNode);
            }
        }
    }

    //判断是空
    public boolean isEmpty() {
        return currentNode.isEmpty();
    }
}
